# # -*- coding: utf-8 -*-
# 1.数据预处理：
import matplotlib.pyplot as plt
from sklearn.datasets import load_breast_cancer
data,target=load_breast_cancer(return_X_y=True)
# 使用MinMaxScaler对数据进行归一化处理。
from sklearn.preprocessing import MinMaxScaler
data=MinMaxScaler().fit_transform(data)
target=MinMaxScaler().fit_transform(target.reshape(-1,1))
# 构造序列数据：使用窗口大小为c的滑动窗口方法来构造输入特征x和对应的标签y。
c=7
x=[]
y=[]
for i in range(len(data)-c):
    x.append(data[i:i+c])
    y.append(target[i+c])
import torch
x=torch.tensor(x,dtype=torch.float)
y=torch.tensor(y,dtype=torch.float)
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test=train_test_split(x,y)
# 2.模型构建：
# 使用GRU构建模型
class gru(torch.nn.Module):
    def __init__(self, *args, **kwargs) -> None:
        super().__init__(*args, **kwargs)
        self.gru1=torch.nn.GRU(input_size=x_train.shape[2],hidden_size=16,batch_first=True)
        self.gru2=torch.nn.GRU(input_size=16,hidden_size=24,batch_first=True)
        self.fc=torch.nn.Linear(in_features=24,out_features=1)
    def forward(self,x):
        x,_=self.gru1(x)
        x,_=self.gru2(x)
        x=self.fc(x[:,-1,:])
        return x
# 3.模型训练：
model=gru()
# 使用均方误差（MSE）作为损失函数。
loss_fn=torch.nn.MSELoss()
# 使用Adam优化器。
op=torch.optim.Adam(model.parameters(),lr=0.001)
# 4.模型预测与评估：
# 使用训练好的模型对测试集进行预测。
# 将预测结果与实际标签进行可视化对比。
loss_list=[]
for i in range(1000):
    op.zero_grad()
    h=model(x_train)
    loss=loss_fn(h,y_train)
    loss.backward()
    loss_list.append(loss)
    op.step()
    if i%10==0:
        print(i,loss)
# 5.可视化：
# 使用matplotlib库绘制预测结果与实际标签的对比图，其中预测结果用红色表示，实际标签用绿色表示。
# 模型调优，考题中要求使用体现不同优化方案的要求，比如超参数方面的，比如说分类精度低的数据集的增强；比如说调整网络结构，比如说调整优化器学习率等；不能只是增加epoch大小，或者调整batch_size就可以，必须采用两种或者两种以上的调优方法进行调优，最终结论要给出综合各种方法调优得出的综合结论
me=model.eval()
plt.plot(me.detach().numpy(),c='r')
plt.plot(y_test.numpy(),c='g')
plt.show()